package com.oss.robot.project;

import java.util.List;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.HasChildFilter;
import org.htmlparser.filters.HasParentFilter;
import org.htmlparser.filters.HasSiblingFilter;
import org.htmlparser.filters.LinkStringFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import com.oss.model.Project;
import com.oss.robot.BaseRobot;

/**
 * @author xueqiang.mi
 * @since 2010-7-25
 */
public class ApacheRobot extends BaseRobot {

	static public final String URL = "http://projects.apache.org/indexes/language.html";
	static public final String SOURCE = "Apache";
	static public final String LICENSE = "Apache License 2.0";
	static public final Integer TASK_NUMBER_PER_TIME = 20;

	public void retrieveProjects() throws Exception {
		Parser parser = new Parser(URL);
		NodeList nodeList = parser.extractAllNodesThatMatch(new AndFilter(
				new TagNameFilter("ul"), new HasSiblingFilter(new AndFilter(
						new TagNameFilter("h3"), new HasChildFilter(
								new HasAttributeFilter("name", "Java"))))));

		nodeList = nodeList.extractAllNodesThatMatch(new AndFilter(
				new LinkStringFilter("/"), new HasParentFilter(
						new TagNameFilter("li"))), true);

		for (Node node : nodeList.toNodeArray()) {
			// 生成项目名称
			String name = node.getFirstChild().getText().replaceFirst(
					"Apache\\s+", "").replaceFirst("\\s+\\(incubating\\)", "")
					.trim();
			if (name.startsWith(".NET")) {// 忽略一个项目
				continue;
			}
			String url = ((LinkTag) node).getLink();
			Project prj = new Project(name, LICENSE, SOURCE, url);

			// 获得项目描述信息
			Node n = node.getNextSibling();
			while (!(n instanceof Div)) {
				n = n.getNextSibling();
			}
			if (n.getFirstChild() != null) {
				String desc = n.getFirstChild().getText().trim();
				prj.setDescription(desc);
			}
			prj.setLabel(name);
			prj.setTag("others");
			prj.setEnabled(false);
			prjService.add(prj);
		}
	}

	@SuppressWarnings("serial")
	public void retrieveUrls() throws ParserException {
		List<Project> prjs = prjService.getInvalidPrjsBySource(SOURCE);
		int endIndex = TASK_NUMBER_PER_TIME < prjs.size() ? TASK_NUMBER_PER_TIME
				: prjs.size();
		for (int i = 0; i < endIndex; i++) {
			Project prj = prjs.get(i);
			Parser parser = new Parser(prj.getUrl());
			NodeList nodeList = parser
					.extractAllNodesThatMatch(new NodeFilter() {
						@Override
						public boolean accept(Node node) {
							if (node instanceof TableColumn) {
								Node n = node.getFirstChild();
								if (n != null
										&& n.getText()
												.equals("Project Website")) {
									return true;
								}
							}
							return false;
						}
					});
			Node n = nodeList.elementAt(0).getNextSibling();
			while (!(n instanceof TableColumn)) {
				n = n.getNextSibling();
			}
			nodeList = n.getChildren().extractAllNodesThatMatch(
					new LinkStringFilter("/"));
			if (nodeList.size() == 1) {
				n = nodeList.elementAt(0);
				prj.setUrl(((LinkTag) n).getLink());
				prj.setEnabled(true);
				prjService.save(prj);
			}
		}
	}
}
